#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <list>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <NetEngine_Include/XyRyNet_CommHdr.h>
#include <NetEngine_Include/XyRyNet_Types.h>
#include <NetEngine_Include/XyRyNet_ProtocolHdr.h>
#include <NetEngine_Include/NetEngine_Core/NetCore_Define.h>
#include <NetEngine_Include/NetEngine_Core/NetCore_Error.h>

//g++ -std=gnu++11 -Wall -g TestFor_CoreBroad.cpp -o TestFor_CoreBroad -L ../NetEngine_Release/NetEngine_Release/NetEngine_BaseLib -L ../NetEngine_Release/NetEngine_Release/NetEngine_Core -lNetEngine_BaseLib -lNetEngine_Algorithm -lNetEngine_Core -lNetEngine_ManagePool -Wl,-rpath=../NetEngine_Release/NetEngine_Release/NetEngine_BaseLib:../NetEngine_Release/NetEngine_Release/NetEngine_Core

SOCKET m_Socket;

//TCP
int main(int argc,char **argv)
{
    SOCKET hSocket;

    if (argc > 1)
    {
        if (NetCore_GroupCast_RVCreate(&hSocket,"224.0.2.100",30000))
        {
            printf("NetCore_GroupCast_RVCreate\n");
        }
        while (1)
        {
            int nLen = 2048;
            TCHAR tszMsgBuffer[2048];
            memset(tszMsgBuffer,'\0',sizeof(tszMsgBuffer));

            SOCKET m_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
            if (SOCKET_ERROR == m_Socket)
            {
                return FALSE;
            }
            int bReuse = 1;
            if (SOCKET_ERROR == setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, (char *)&bReuse, sizeof(int)))
            {
                return FALSE;
            }
            int nLoop = 1;
            if (SOCKET_ERROR == setsockopt(m_Socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&nLoop, sizeof(int)))
            {
                return FALSE;
            }

            struct sockaddr_in st_SockAddr;
            st_SockAddr.sin_family = AF_INET;
            st_SockAddr.sin_port = htons(30000);
            st_SockAddr.sin_addr.s_addr = INADDR_ANY;
            if (SOCKET_ERROR == bind(m_Socket, (sockaddr *)&st_SockAddr, sizeof(st_SockAddr)))
            {
                return FALSE;
            }
            ip_mreq st_IPCast;
            st_IPCast.imr_interface.s_addr = INADDR_ANY;
            st_IPCast.imr_multiaddr.s_addr = inet_addr("224.0.2.100");
            if (SOCKET_ERROR == setsockopt(m_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&st_IPCast, sizeof(st_IPCast)))
            {
                return FALSE;
            }

            struct sockaddr_in st_RecvAddr;
            socklen_t nSize = sizeof(st_RecvAddr);
            int nRet = recvfrom(m_Socket, tszMsgBuffer, nLen, 0, (sockaddr *)&st_RecvAddr, &nSize);
            if (nRet <= 0)
            {
                return FALSE;
            }
            /*
            if (NetCore_GroupCast_RVecv(hSocket,tszMsgBuffer,&nLen))
            {
                printf("%d:%s\n",nLen,tszMsgBuffer);
            }
            else
            {
                printf("%lX\n",NetCore_GetLastError());
            }*/
            sleep(1);
        }
    }
    else
    {
        if (NetCore_GroupCast_SDCreate(&hSocket,"224.0.2.100",30000))
        {
            printf("NetCore_GroupCast_SDCreate\n");
        }
        while (1)
        {
            if (NetCore_GroupCast_SDend(hSocket,"123456",6))
            {
                printf("123123\n");
            }
            else
            {
                printf("%lX\n",NetCore_GetLastError());
            }
            sleep(1);
        }
    }

    return 0;
}
